package com.itheima.core.controller;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.common.pojo.PageInfo;
import com.itheima.common.pojo.PageRequestDto;
import com.itheima.common.pojo.Result;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

@Slf4j
public class AbstractCoreController<T> {

    private IService<T> iService;

    public AbstractCoreController(IService<T> iService) {
        this.iService = iService;
    }

    /**
     * 添加
     */
    @PostMapping
//    @ApiOperation(value = "insert",notes = "添加频道")
    public Result<T> insert(@RequestBody T t){

        boolean flag = iService.save(t);
        if (!flag){
                return Result.error();
            }

        return Result.ok(t);
    }

    /**
     * 根据id删除
     */
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Serializable id){
        boolean flag = iService.removeById(id);
        if (!flag){
            return Result.error();
        }
        return Result.ok();
    }


    /**
     *  修改
     */
    @PutMapping()
    public Result update(@RequestBody T t){
        boolean flag = iService.updateById(t);
        if (!flag){
            return Result.error();
        }
        return Result.ok();
    }

    /**
     * 根据id查询
     */
    @GetMapping("/{id}")
    public Result<T> findById(@PathVariable(value = "id") Serializable id){

        T t = iService.getById(id);
        if (t == null){
            return Result.error();
        }
        return Result.ok(t);
    }
    /**
     * 查询所有
     *
     */
    @GetMapping()
    public Result<List<T>> findAll(){
        List<T> list = iService.list();
        return Result.ok(list);

    }

    /**
     * 通用条件分页查询
     */
    @PostMapping(value = "/search")
    public Result<PageInfo<T>> findByPage(@RequestBody PageRequestDto<T> pageRequestDto){
        Page page = new Page<>(pageRequestDto.getPage(),pageRequestDto.getSize());

        //条件
        QueryWrapper<T> queryWrapper = getWrapper(pageRequestDto.getBody());
        IPage iPage = iService.page(page,queryWrapper);
        PageInfo<T> pageInfo = new PageInfo<>(iPage.getCurrent(),pageRequestDto.getSize(),
                iPage.getTotal(),iPage.getPages(),iPage.getRecords());
        return Result.ok(pageInfo);
    }

    private QueryWrapper<T> getWrapper(T body) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (body == null) {
            return queryWrapper;
        }
        Field[] declaredFields = body.getClass().getDeclaredFields();

        for (Field declaredField : declaredFields) {
            try {
                if (declaredField.isAnnotationPresent(TableId.class) || declaredField.getName().equals("serialVersionUID")){
                    //遇到
                    continue;
                }
                //属性描述器
                PropertyDescriptor propDesc = new PropertyDescriptor(declaredField.getName(),body.getClass());
                //获取这个值  先获取读方法的方法对象,并调用获取里面的值
                Object value = propDesc.getReadMethod().invoke(body);
                //如果是字符串
                TableField annotation = declaredField.getAnnotation(TableField.class);
                //如果传递的值为空则不做处理
                if(value != null) {
                    //如是字符串 则用like
                    if (value.getClass().getName().equals("java.lang.String")) {
                        queryWrapper.like(annotation.value(), value);
                    } else {
                        //否则使用=号
                        queryWrapper.eq(annotation.value(), value);
                    }
                }
            } catch (Exception e) {
                log.error(e.getCause().getLocalizedMessage());
                e.printStackTrace();
            }

        }

        return queryWrapper;
    }

    //获取分页对象
    protected PageInfo<T> getPageInfo(IPage<T> iPage){
        return new PageInfo<T>(iPage.getCurrent(),iPage.getSize(),iPage.getTotal(),iPage.getPages(),iPage.getRecords());
    }


}
